/*
 * @Author: Kiro AI Assistant
 * @Date: 2025-01-10
 * @Description: 音乐播放器 ViewModel - MVVM 架构的核心业务逻辑
 */

import 'dart:async';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:audioplayers/audioplayers.dart';
import '../models/music_item_model.dart';
import '../models/play_mode.dart';
import '../services/audio_player_tool.dart';
import '../utils/error_handler.dart';
import '../services/music_api_service.dart';
import '../utils/performance_monitor.dart';

/// 音乐播放器 ViewModel
/// 管理音乐播放的核心业务逻辑和状态
class MusicPlayerViewModel extends ChangeNotifier {
  // ==================== 核心状态 ====================

  /// 播放状态
  final ValueNotifier<bool> isPlaying = ValueNotifier(false);

  /// 播放位置
  final ValueNotifier<Duration> position = ValueNotifier(Duration.zero);

  /// 播放时长
  final ValueNotifier<Duration> duration = ValueNotifier(Duration.zero);

  /// 播放模式
  final ValueNotifier<PlayMode> playMode = ValueNotifier(PlayMode.listLoop);

  // ==================== 私有状态 ====================

  /// 当前播放的音乐
  MusicItemModel? _currentTrack;

  /// 播放列表
  final List<MusicItemModel> _playlist = [];

  /// 当前播放索引
  int _currentIndex = -1;

  /// 是否正在加载
  bool _isLoading = false;

  /// 音频时长缓存
  final Map<String, Duration> _durationCache = {};

  /// 流订阅
  StreamSubscription<Duration>? _positionSubscription;
  StreamSubscription<Duration>? _durationSubscription;
  StreamSubscription<PlayerState>? _stateSubscription;
  StreamSubscription<void>? _completionSubscription;
  StreamSubscription<String>? _errorSubscription;

  // ==================== 构造函数 ====================

  MusicPlayerViewModel() {
    _initializeAudioPlayer();
  }

  // ==================== 公共属性 ====================

  /// 当前播放的音乐
  MusicItemModel? get currentTrack => _currentTrack;

  /// 播放列表
  List<MusicItemModel> get playlist => List.unmodifiable(_playlist);

  /// 当前播放索引
  int get currentIndex => _currentIndex;

  /// 是否正在加载
  bool get isLoading => _isLoading;

  /// 是否有播放列表
  bool get hasPlaylist => _playlist.isNotEmpty;

  /// 是否有当前播放的音乐
  bool get hasCurrentTrack => _currentTrack != null;

  /// 当前音乐标题
  String get currentTrackTitle => _currentTrack?.title ?? '';

  /// 当前音乐艺术家
  String get currentTrackArtist => _currentTrack?.artist ?? '';

  /// 当前音乐专辑
  String get currentTrackAlbum => _currentTrack?.album ?? '';

  /// 当前音乐专辑封面
  String? get currentTrackAlbumArt => _currentTrack?.albumArt;

  /// 是否可以播放上一首
  bool get canPlayPrevious => _currentIndex > 0;

  /// 是否可以播放下一首
  bool get canPlayNext => _currentIndex < _playlist.length - 1;

  // ==================== 初始化 ====================

  /// 初始化音频播放器
  Future<void> _initializeAudioPlayer() async {
    try {
      await AudioPlayerTool.initialize();
      _setupAudioListeners();
      if (kDebugMode) {
        debugPrint('MusicPlayerViewModel 初始化成功');
      }
    } catch (error, stackTrace) {
      ErrorHandler.handleError(error, stackTrace);
    }
  }

  /// 设置音频监听器
  void _setupAudioListeners() {
    // 监听播放位置变化
    _positionSubscription = AudioPlayerTool.positionStream.listen((pos) {
      position.value = pos;
    });

    // 监听播放时长变化
    _durationSubscription = AudioPlayerTool.durationStream.listen((dur) {
      duration.value = dur;
      // 缓存时长信息
      if (_currentTrack != null && dur.inMilliseconds > 0) {
        _durationCache[_currentTrack!.id] = dur;
      }
    });

    // 监听播放状态变化
    _stateSubscription = AudioPlayerTool.stateStream.listen((state) {
      final wasPlaying = isPlaying.value;
      isPlaying.value = state == PlayerState.playing;

      // 状态变化时通知监听器
      if (wasPlaying != isPlaying.value) {
        notifyListeners();
      }
    });

    // 监听播放完成
    _completionSubscription = AudioPlayerTool.completionStream.listen((_) {
      _handlePlaybackCompletion();
    });

    // 监听播放错误
    _errorSubscription = AudioPlayerTool.errorStream.listen((error) {
      ErrorHandler.handleError(Exception(error), StackTrace.current);
    });
  }

  // ==================== 播放控制 ====================

  /// 播放指定音乐
  Future<void> play(MusicItemModel track) async {
    await AudioPerformanceTracker.track('play', () async {
      try {
        _isLoading = true;
        notifyListeners();

        // 获取播放URL
        String playUrl = await _getPlayUrl(track);
        if (playUrl.isEmpty) {
          throw Exception('无法获取播放链接');
        }

        // 更新当前播放信息
        _currentTrack = track;

        // 查找在播放列表中的索引
        final index = _playlist.indexWhere((item) => item.id == track.id);
        if (index != -1) {
          _currentIndex = index;
        }

        // 从缓存中获取时长
        if (_durationCache.containsKey(track.id)) {
          duration.value = _durationCache[track.id]!;
        }

        // 播放音频
        await AudioPlayerTool.play(playUrl);

        if (kDebugMode) {
          debugPrint('开始播放: ${track.title} - ${track.artist}');
        }
      } catch (error, stackTrace) {
        ErrorHandler.handleError(error, stackTrace);
      } finally {
        _isLoading = false;
        notifyListeners();
      }
    }, track.title);
  }

  /// 暂停播放
  Future<void> pause() async {
    await AudioPerformanceTracker.track('pause', () async {
      try {
        await AudioPlayerTool.pause();
        if (kDebugMode) {
          debugPrint('播放已暂停');
        }
      } catch (error, stackTrace) {
        ErrorHandler.handleError(error, stackTrace);
      }
    });
  }

  /// 继续播放
  Future<void> resume() async {
    try {
      await AudioPlayerTool.resume();
      if (kDebugMode) {
        debugPrint('播放已继续');
      }
    } catch (error, stackTrace) {
      ErrorHandler.handleError(error, stackTrace);
    }
  }

  /// 停止播放
  Future<void> stop() async {
    try {
      await AudioPlayerTool.stop();
      position.value = Duration.zero;
      isPlaying.value = false;
      if (kDebugMode) {
        debugPrint('播放已停止');
      }
    } catch (error, stackTrace) {
      ErrorHandler.handleError(error, stackTrace);
    }
  }

  /// 跳转到指定位置
  Future<void> seekTo(Duration targetPosition) async {
    await AudioPerformanceTracker.track('seek', () async {
      try {
        await AudioPlayerTool.seekTo(targetPosition);
        if (kDebugMode) {
          debugPrint('跳转到: ${targetPosition.inSeconds}秒');
        }
      } catch (error, stackTrace) {
        ErrorHandler.handleError(error, stackTrace);
      }
    });
  }

  // ==================== 播放列表控制 ====================

  /// 播放下一首
  Future<void> next() async {
    if (_playlist.isEmpty) return;

    int nextIndex;

    switch (playMode.value) {
      case PlayMode.listLoop:
        nextIndex = (_currentIndex + 1) % _playlist.length;
        break;
      case PlayMode.singleLoop:
        nextIndex = _currentIndex; // 单曲循环保持当前索引
        break;
      case PlayMode.shuffle:
        nextIndex = _getRandomIndex();
        break;
    }

    if (nextIndex >= 0 && nextIndex < _playlist.length) {
      await playAtIndex(nextIndex);
    }
  }

  /// 播放上一首
  Future<void> previous() async {
    if (_playlist.isEmpty) return;

    int previousIndex;

    switch (playMode.value) {
      case PlayMode.listLoop:
        previousIndex =
            (_currentIndex - 1 + _playlist.length) % _playlist.length;
        break;
      case PlayMode.singleLoop:
        previousIndex = _currentIndex; // 单曲循环保持当前索引
        break;
      case PlayMode.shuffle:
        previousIndex = _getRandomIndex();
        break;
    }

    if (previousIndex >= 0 && previousIndex < _playlist.length) {
      await playAtIndex(previousIndex);
    }
  }

  /// 播放指定索引的音乐
  Future<void> playAtIndex(int index) async {
    if (index < 0 || index >= _playlist.length) return;

    _currentIndex = index;
    await play(_playlist[index]);
  }

  /// 设置播放列表
  void setPlaylist(List<MusicItemModel> newPlaylist, {int? startIndex}) {
    _playlist.clear();
    _playlist.addAll(newPlaylist);

    if (startIndex != null &&
        startIndex >= 0 &&
        startIndex < _playlist.length) {
      _currentIndex = startIndex;
    } else {
      _currentIndex = _playlist.isNotEmpty ? 0 : -1;
    }

    notifyListeners();

    if (kDebugMode) {
      debugPrint('播放列表已更新，共 ${_playlist.length} 首歌曲');
    }
  }

  /// 添加音乐到播放列表
  void addToPlaylist(MusicItemModel track) {
    _playlist.add(track);

    // 如果是第一首歌，设置为当前索引
    if (_playlist.length == 1) {
      _currentIndex = 0;
    }

    notifyListeners();

    if (kDebugMode) {
      debugPrint('添加到播放列表: ${track.title}');
    }
  }

  /// 从播放列表移除音乐
  void removeFromPlaylist(int index) {
    if (index < 0 || index >= _playlist.length) return;

    final removedTrack = _playlist.removeAt(index);

    // 调整当前播放索引
    if (index < _currentIndex) {
      _currentIndex--;
    } else if (index == _currentIndex) {
      // 如果移除的是当前播放的歌曲
      if (_playlist.isEmpty) {
        _currentIndex = -1;
        _currentTrack = null;
        stop();
      } else {
        // 调整到合适的索引
        if (_currentIndex >= _playlist.length) {
          _currentIndex = _playlist.length - 1;
        }
      }
    }

    notifyListeners();

    if (kDebugMode) {
      debugPrint('从播放列表移除: ${removedTrack.title}');
    }
  }

  /// 清空播放列表
  void clearPlaylist() {
    _playlist.clear();
    _currentIndex = -1;
    _currentTrack = null;
    stop();
    notifyListeners();

    if (kDebugMode) {
      debugPrint('播放列表已清空');
    }
  }

  // ==================== UI 交互方法 ====================

  /// 切换播放/暂停状态
  Future<void> togglePlayPause() async {
    if (isPlaying.value) {
      await pause();
    } else {
      if (_currentTrack != null) {
        await resume();
      } else if (_playlist.isNotEmpty) {
        await playAtIndex(_currentIndex >= 0 ? _currentIndex : 0);
      }
    }
  }

  /// 设置播放模式
  void setPlayMode(PlayMode mode) {
    playMode.value = mode;
    notifyListeners();

    if (kDebugMode) {
      debugPrint('播放模式已切换为: ${mode.displayName}');
    }
  }

  /// 切换到下一个播放模式
  void togglePlayMode() {
    setPlayMode(playMode.value.next);
  }

  // ==================== 私有方法 ====================

  /// 获取播放URL
  Future<String> _getPlayUrl(MusicItemModel track) async {
    // 如果已经有播放URL，直接返回
    if (track.audioUrl.isNotEmpty) {
      return track.audioUrl;
    }

    // 如果是QQ音乐，需要通过API获取播放链接
    if (track.sourceType == 'qq_music' || track.sourceType == 'qq') {
      try {
        final apiService = MusicApiService();
        final playUrl = await apiService.loadStrapTrack(
            trackId: track.id, sourceType: track.sourceType);

        if (kDebugMode) {
          debugPrint('获取到播放链接: $playUrl');
        }

        return playUrl;
      } catch (error) {
        if (kDebugMode) {
          debugPrint('获取QQ音乐播放链接失败: $error');
        }
        return '';
      }
    }

    return track.audioUrl;
  }

  /// 处理播放完成
  void _handlePlaybackCompletion() {
    if (kDebugMode) {
      debugPrint('播放完成');
    }

    // 根据播放模式决定下一步操作
    switch (playMode.value) {
      case PlayMode.singleLoop:
        // 单曲循环：重新播放当前歌曲
        if (_currentTrack != null) {
          play(_currentTrack!);
        }
        break;
      case PlayMode.listLoop:
      case PlayMode.shuffle:
        // 列表循环或随机播放：播放下一首
        next();
        break;
    }
  }

  /// 获取随机索引
  int _getRandomIndex() {
    if (_playlist.length <= 1) return _currentIndex;

    int randomIndex;
    do {
      randomIndex = Random().nextInt(_playlist.length);
    } while (randomIndex == _currentIndex);

    return randomIndex;
  }

  /// 预加载下一首歌曲信息
  Future<void> preloadNextTrack() async {
    if (_playlist.isEmpty || _currentIndex < 0) return;

    int nextIndex = (_currentIndex + 1) % _playlist.length;
    final nextTrack = _playlist[nextIndex];

    // 预加载播放URL和时长信息
    try {
      await _getPlayUrl(nextTrack);
    } catch (error) {
      // 预加载失败不影响正常播放
      if (kDebugMode) {
        debugPrint('预加载下一首失败: $error');
      }
    }
  }

  /// 预加载下一页数据（用于播放列表页面）
  Future<void> preloadNextPage() async {
    // 这里可以实现预加载逻辑，比如预加载更多歌曲信息
    // 目前主要是预加载下一首歌曲的播放链接
    await preloadNextTrack();

    if (kDebugMode) {
      debugPrint('预加载下一页数据完成');
    }
  }

  // ==================== 资源清理 ====================

  @override
  void dispose() {
    // 取消所有流订阅
    _positionSubscription?.cancel();
    _durationSubscription?.cancel();
    _stateSubscription?.cancel();
    _completionSubscription?.cancel();
    _errorSubscription?.cancel();

    // 释放 ValueNotifier
    isPlaying.dispose();
    position.dispose();
    duration.dispose();
    playMode.dispose();

    // 清理缓存
    _durationCache.clear();

    if (kDebugMode) {
      debugPrint('MusicPlayerViewModel 已释放资源');
    }

    super.dispose();
  }
}
